import 'dart:io';
import 'dart:convert';
import 'package:path/path.dart' as path;
import 'package:get/get.dart';
import '../models/prompt_model.dart';

/// 文件系统存储服务 - File System Storage Service
/// 负责管理 Prompt 数据的本地文件存储，支持多种格式和版本管理
class FileSystemService extends GetxService {
  static FileSystemService get to => Get.find();

  // 存储路径配置 - Storage Path Configuration
  late String _baseStoragePath;
  late String _promptsPath;
  late String _versionsPath;
  late String _configPath;
  late String _indexPath;

  // 支持的文件格式 - Supported File Formats
  static const List<String> supportedFormats = ['md', 'txt', 'doc', 'pdf'];
  
  // 配置信息 - Configuration
  final Map<String, dynamic> _config = {};
  
  // 搜索索引 - Search Index
  final Map<String, List<String>> _searchIndex = {};

  @override
  Future<void> onInit() async {
    super.onInit();
    await _initializeStorage();
  }

  /// 初始化存储系统 - Initialize Storage System
  Future<void> _initializeStorage() async {
    try {
      // 获取应用文档目录 - Get application documents directory
      final documentsDir = Directory.current.path;
      _baseStoragePath = path.join(documentsDir, 'prompt_manager_data');
      
      // 创建存储目录结构 - Create storage directory structure
      _promptsPath = path.join(_baseStoragePath, 'prompts');
      _versionsPath = path.join(_baseStoragePath, 'versions');
      _configPath = path.join(_baseStoragePath, 'config');
      _indexPath = path.join(_baseStoragePath, 'index');

      await _createDirectories();
      await _loadConfiguration();
      await _buildSearchIndex();
      
      Get.log('文件系统存储服务初始化完成 - FileSystemService initialized');
    } catch (e) {
      Get.log('文件系统存储服务初始化失败: $e');
      throw Exception('存储系统初始化失败: $e');
    }
  }

  /// 创建必要的目录 - Create Necessary Directories
  Future<void> _createDirectories() async {
    final directories = [
      _baseStoragePath,
      _promptsPath,
      _versionsPath,
      _configPath,
      _indexPath,
    ];

    for (final dirPath in directories) {
      final dir = Directory(dirPath);
      if (!await dir.exists()) {
        await dir.create(recursive: true);
        Get.log('创建目录: $dirPath');
      }
    }

    // 为每种格式创建子目录 - Create subdirectories for each format
    for (final format in supportedFormats) {
      final formatDir = Directory(path.join(_promptsPath, format));
      if (!await formatDir.exists()) {
        await formatDir.create(recursive: true);
      }
    }
  }

  /// 加载配置 - Load Configuration
  Future<void> _loadConfiguration() async {
    try {
      final configFile = File(path.join(_configPath, 'app_config.json'));
      if (await configFile.exists()) {
        final content = await configFile.readAsString();
        final config = jsonDecode(content) as Map<String, dynamic>;
        _config.addAll(config);
      } else {
        // 创建默认配置 - Create default configuration
        _config.addAll({
          'version': '1.0.0',
          'created_at': DateTime.now().toIso8601String(),
          'auto_save_interval': 30, // 秒 - seconds
          'max_versions_per_prompt': 50,
          'default_format': 'md',
          'enable_search_index': true,
          'guest_user_id': 'guest_${DateTime.now().millisecondsSinceEpoch}',
        });
        await _saveConfiguration();
      }
    } catch (e) {
      Get.log('加载配置失败: $e');
    }
  }

  /// 保存配置 - Save Configuration
  Future<void> _saveConfiguration() async {
    try {
      final configFile = File(path.join(_configPath, 'app_config.json'));
      await configFile.writeAsString(jsonEncode(_config));
    } catch (e) {
      Get.log('保存配置失败: $e');
    }
  }

  /// 构建搜索索引 - Build Search Index
  Future<void> _buildSearchIndex() async {
    try {
      _searchIndex.clear();
      
      // 遍历所有 Prompt 文件 - Iterate through all Prompt files
      for (final format in supportedFormats) {
        final formatDir = Directory(path.join(_promptsPath, format));
        if (await formatDir.exists()) {
          await for (final entity in formatDir.list()) {
            if (entity is Directory) {
              await _indexPromptDirectory(entity, format);
            }
          }
        }
      }
      
      // 保存搜索索引 - Save search index
      await _saveSearchIndex();
    } catch (e) {
      Get.log('构建搜索索引失败: $e');
    }
  }

  /// 索引 Prompt 目录 - Index Prompt Directory
  Future<void> _indexPromptDirectory(Directory promptDir, String format) async {
    try {
      final promptId = path.basename(promptDir.path);
      final metaFile = File(path.join(promptDir.path, 'meta.json'));
      
      if (await metaFile.exists()) {
        final content = await metaFile.readAsString();
        final meta = jsonDecode(content) as Map<String, dynamic>;
        
        // 提取关键词用于搜索 - Extract keywords for search
        final keywords = <String>[];
        keywords.add(meta['title']?.toString().toLowerCase() ?? '');
        keywords.add(meta['description']?.toString().toLowerCase() ?? '');
        keywords.addAll((meta['tags'] as List<dynamic>? ?? [])
            .map((tag) => tag.toString().toLowerCase()));
        
        // 读取内容文件进行全文索引 - Read content file for full-text indexing
        final contentFile = File(path.join(promptDir.path, 'content.$format'));
        if (await contentFile.exists()) {
          final contentText = await contentFile.readAsString();
          keywords.addAll(contentText.toLowerCase().split(RegExp(r'\s+')));
        }
        
        _searchIndex[promptId] = keywords.where((k) => k.isNotEmpty).toList();
      }
    } catch (e) {
      Get.log('索引 Prompt 目录失败: $e');
    }
  }

  /// 保存搜索索引 - Save Search Index
  Future<void> _saveSearchIndex() async {
    try {
      final indexFile = File(path.join(_indexPath, 'search_index.json'));
      await indexFile.writeAsString(jsonEncode(_searchIndex));
    } catch (e) {
      Get.log('保存搜索索引失败: $e');
    }
  }

  /// 保存 Prompt - Save Prompt
  Future<String> savePrompt(PromptModel prompt) async {
    try {
      final promptId = prompt.id.isEmpty 
          ? _generatePromptId() 
          : prompt.id;
      
      final format = prompt.getFormat().isEmpty ? 'md' : prompt.getFormat();
      final promptDir = Directory(path.join(_promptsPath, format, promptId));
      
      // 创建 Prompt 目录 - Create Prompt directory
      if (!await promptDir.exists()) {
        await promptDir.create(recursive: true);
      }
      
      // 保存元数据 - Save metadata
      await _savePromptMetadata(promptDir.path, prompt);
      
      // 保存内容文件 - Save content file
      await _savePromptContent(promptDir.path, prompt.content, format);
      
      // 创建版本 - Create version
      await _createVersion(promptId, prompt);
      
      // 更新搜索索引 - Update search index
      await _updateSearchIndex(promptId, prompt);
      
      Get.log('Prompt 保存成功: $promptId');
      return promptId;
      
    } catch (e) {
      Get.log('保存 Prompt 失败: $e');
      throw Exception('保存 Prompt 失败: $e');
    }
  }

  /// 生成 Prompt ID - Generate Prompt ID
  String _generatePromptId() {
    return 'prompt_${DateTime.now().millisecondsSinceEpoch}';
  }

  /// 保存 Prompt 元数据 - Save Prompt Metadata
  Future<void> _savePromptMetadata(String promptPath, PromptModel prompt) async {
    final metaFile = File(path.join(promptPath, 'meta.json'));
    final metadata = {
      'id': prompt.id,
      'title': prompt.title,
      'description': prompt.description,
      'category': prompt.category,
      'tags': prompt.tags,
      'format': prompt.getFormat(),
      'created_at': prompt.createdAt.toIso8601String(),
      'updated_at': prompt.getUpdatedAt().toIso8601String(),
      'version': prompt.version,
      'is_favorite': prompt.getIsFavorite(),
      'usage_count': prompt.usageCount,
      'template_variables': prompt.templateVariables.map((v) => v.toJson()).toList(),
    };
    
    await metaFile.writeAsString(jsonEncode(metadata));
  }

  /// 保存 Prompt 内容 - Save Prompt Content
  Future<void> _savePromptContent(String promptPath, String content, String format) async {
    final contentFile = File(path.join(promptPath, 'content.$format'));
    await contentFile.writeAsString(content);
  }

  /// 创建版本 - Create Version
  Future<void> _createVersion(String promptId, PromptModel prompt) async {
    try {
      final versionDir = Directory(path.join(_versionsPath, promptId));
      if (!await versionDir.exists()) {
        await versionDir.create(recursive: true);
      }
      
      final versionId = 'v${prompt.version}_${DateTime.now().millisecondsSinceEpoch}';
      final versionFile = File(path.join(versionDir.path, '$versionId.json'));
      
      final versionData = {
        'id': versionId,
        'prompt_id': promptId,
        'version': prompt.version,
        'content': prompt.content,
        'metadata': {
          'title': prompt.title,
          'description': prompt.description,
          'tags': prompt.tags,
          'format': prompt.getFormat(),
        },
        'created_at': DateTime.now().toIso8601String(),
        'content_length': prompt.content.length,
        'is_auto_save': false, // 可以根据需要设置 - Can be set as needed
        'notes': '', // 版本备注 - Version notes
      };
      
      await versionFile.writeAsString(jsonEncode(versionData));
      
      // 清理旧版本（保留最近的版本） - Clean old versions (keep recent versions)
      await _cleanOldVersions(promptId);
      
    } catch (e) {
      Get.log('创建版本失败: $e');
    }
  }

  /// 清理旧版本 - Clean Old Versions
  Future<void> _cleanOldVersions(String promptId) async {
    try {
      final maxVersions = _config['max_versions_per_prompt'] as int? ?? 50;
      final versionDir = Directory(path.join(_versionsPath, promptId));
      
      if (await versionDir.exists()) {
        final versionFiles = await versionDir
            .list()
            .where((entity) => entity is File && entity.path.endsWith('.json'))
            .cast<File>()
            .toList();
        
        if (versionFiles.length > maxVersions) {
          // 按修改时间排序 - Sort by modification time
          versionFiles.sort((a, b) => 
              b.lastModifiedSync().compareTo(a.lastModifiedSync()));
          
          // 删除多余的版本 - Delete excess versions
          for (int i = maxVersions; i < versionFiles.length; i++) {
            await versionFiles[i].delete();
          }
        }
      }
    } catch (e) {
      Get.log('清理旧版本失败: $e');
    }
  }

  /// 更新搜索索引 - Update Search Index
  Future<void> _updateSearchIndex(String promptId, PromptModel prompt) async {
    try {
      final keywords = <String>[];
      keywords.add(prompt.title.toLowerCase());
      keywords.add(prompt.description.toLowerCase());
      keywords.addAll(prompt.tags.map((tag) => tag.toLowerCase()));
      keywords.addAll(prompt.content.toLowerCase().split(RegExp(r'\s+')));
      
      _searchIndex[promptId] = keywords.where((k) => k.isNotEmpty).toList();
      await _saveSearchIndex();
    } catch (e) {
      Get.log('更新搜索索引失败: $e');
    }
  }

  /// 加载 Prompt - Load Prompt
  Future<PromptModel?> loadPrompt(String promptId, {String? format}) async {
    try {
      // 如果没有指定格式，尝试所有格式 - If no format specified, try all formats
      final formatsToTry = format != null ? [format] : supportedFormats;
      
      for (final fmt in formatsToTry) {
        final promptDir = Directory(path.join(_promptsPath, fmt, promptId));
        if (await promptDir.exists()) {
          return await _loadPromptFromDirectory(promptDir, fmt);
        }
      }
      
      return null;
    } catch (e) {
      Get.log('加载 Prompt 失败: $e');
      return null;
    }
  }

  /// 从目录加载 Prompt - Load Prompt from Directory
  Future<PromptModel> _loadPromptFromDirectory(Directory promptDir, String format) async {
    // 加载元数据 - Load metadata
    final metaFile = File(path.join(promptDir.path, 'meta.json'));
    final metaContent = await metaFile.readAsString();
    final metadata = jsonDecode(metaContent) as Map<String, dynamic>;
    
    // 加载内容 - Load content
    final contentFile = File(path.join(promptDir.path, 'content.$format'));
    final content = await contentFile.readAsString();
    
    // 创建 PromptModel - Create PromptModel
    return PromptModel.fromJson({
      ...metadata,
      'content': content,
    });
  }

  /// 获取所有 Prompt 列表 - Get All Prompts List
  Future<List<PromptModel>> getAllPrompts({String? format, String? category}) async {
    try {
      final prompts = <PromptModel>[];
      final formatsToScan = format != null ? [format] : supportedFormats;
      
      for (final fmt in formatsToScan) {
        final formatDir = Directory(path.join(_promptsPath, fmt));
        if (await formatDir.exists()) {
          await for (final entity in formatDir.list()) {
            if (entity is Directory) {
              try {
                final prompt = await _loadPromptFromDirectory(entity, fmt);
                if (category == null || prompt.category == category) {
                  prompts.add(prompt);
                }
              } catch (e) {
                Get.log('加载 Prompt 失败: ${entity.path}, 错误: $e');
              }
            }
          }
        }
      }
      
      // 按更新时间排序 - Sort by update time
      prompts.sort((a, b) => b.getUpdatedAt().compareTo(a.getUpdatedAt()));
      return prompts;
      
    } catch (e) {
      Get.log('获取 Prompt 列表失败: $e');
      return [];
    }
  }

  /// 搜索 Prompt - Search Prompts
  Future<List<PromptModel>> searchPrompts(String query, {
    String? format,
    String? category,
    List<String>? tags,
  }) async {
    try {
      if (query.isEmpty) {
        return await getAllPrompts(format: format, category: category);
      }
      
      final queryKeywords = query.toLowerCase().split(RegExp(r'\s+'));
      final matchingIds = <String>[];
      
      // 在搜索索引中查找匹配的 Prompt ID - Find matching Prompt IDs in search index
      for (final entry in _searchIndex.entries) {
        final promptId = entry.key;
        final keywords = entry.value;
        
        bool matches = queryKeywords.every((queryKeyword) =>
            keywords.any((keyword) => keyword.contains(queryKeyword)));
        
        if (matches) {
          matchingIds.add(promptId);
        }
      }
      
      // 加载匹配的 Prompt - Load matching Prompts
      final results = <PromptModel>[];
      for (final promptId in matchingIds) {
        final prompt = await loadPrompt(promptId, format: format);
        if (prompt != null) {
          // 应用额外的筛选条件 - Apply additional filter conditions
          if (category != null && prompt.category != category) continue;
          if (tags != null && !tags.every((tag) => prompt.tags.contains(tag))) continue;
          
          results.add(prompt);
        }
      }
      
      return results;
    } catch (e) {
      Get.log('搜索 Prompt 失败: $e');
      return [];
    }
  }

  /// 删除 Prompt - Delete Prompt
  Future<bool> deletePrompt(String promptId, {String? format}) async {
    try {
      bool deleted = false;
      final formatsToTry = format != null ? [format] : supportedFormats;
      
      for (final fmt in formatsToTry) {
        final promptDir = Directory(path.join(_promptsPath, fmt, promptId));
        if (await promptDir.exists()) {
          await promptDir.delete(recursive: true);
          deleted = true;
        }
      }
      
      // 删除版本历史 - Delete version history
      final versionDir = Directory(path.join(_versionsPath, promptId));
      if (await versionDir.exists()) {
        await versionDir.delete(recursive: true);
      }
      
      // 从搜索索引中移除 - Remove from search index
      _searchIndex.remove(promptId);
      await _saveSearchIndex();
      
      return deleted;
    } catch (e) {
      Get.log('删除 Prompt 失败: $e');
      return false;
    }
  }

  /// 获取版本历史 - Get Version History
  Future<List<Map<String, dynamic>>> getVersionHistory(String promptId) async {
    try {
      final versionDir = Directory(path.join(_versionsPath, promptId));
      if (!await versionDir.exists()) {
        return [];
      }
      
      final versions = <Map<String, dynamic>>[];
      await for (final entity in versionDir.list()) {
        if (entity is File && entity.path.endsWith('.json')) {
          try {
            final content = await entity.readAsString();
            final versionData = jsonDecode(content) as Map<String, dynamic>;
            versions.add(versionData);
          } catch (e) {
            Get.log('读取版本文件失败: ${entity.path}, 错误: $e');
          }
        }
      }
      
      // 按创建时间排序 - Sort by creation time
      versions.sort((a, b) {
        final aTime = DateTime.parse(a['created_at'] as String);
        final bTime = DateTime.parse(b['created_at'] as String);
        return bTime.compareTo(aTime);
      });
      
      return versions;
    } catch (e) {
      Get.log('获取版本历史失败: $e');
      return [];
    }
  }

  /// 恢复版本 - Restore Version
  Future<bool> restoreVersion(String promptId, String versionId) async {
    try {
      final versionFile = File(path.join(_versionsPath, promptId, '$versionId.json'));
      if (!await versionFile.exists()) {
        return false;
      }
      
      final content = await versionFile.readAsString();
      final versionData = jsonDecode(content) as Map<String, dynamic>;
      
      // 重新构建 PromptModel - Rebuild PromptModel
      final prompt = PromptModel(
        id: promptId,
        title: versionData['metadata']['title'] as String,
        description: versionData['metadata']['description'] as String,
        content: versionData['content'] as String,
        category: 'restored', // 可以从元数据中获取 - Can be obtained from metadata
        tags: List<String>.from(versionData['metadata']['tags'] as List),
        fileFormat: versionData['metadata']['format'] as String,
        filePath: '',
        createdAt: DateTime.parse(versionData['created_at'] as String),
        lastModified: DateTime.now(),
        version: int.parse((versionData['version'] as String).split('.').first),
        metadata: {'isFavorite': false},
        usageCount: 0,
        templateVariables: [], // 需要从原始数据恢复 - Need to restore from original data
      );
      
      // 保存恢复的版本 - Save restored version
      await savePrompt(prompt);
      return true;
      
    } catch (e) {
      Get.log('恢复版本失败: $e');
      return false;
    }
  }

  /// 导出 Prompt - Export Prompt
  Future<String?> exportPrompt(String promptId, String exportFormat, {String? outputPath}) async {
    try {
      final prompt = await loadPrompt(promptId);
      if (prompt == null) return null;
      
      final exportData = _formatExportData(prompt, exportFormat);
      final fileName = '${prompt.title.replaceAll(RegExp(r'[^\w\s-]'), '')}_${DateTime.now().millisecondsSinceEpoch}.$exportFormat';
      
      final filePath = outputPath ?? path.join(_baseStoragePath, 'exports', fileName);
      final exportFile = File(filePath);
      
      // 确保导出目录存在 - Ensure export directory exists
      await exportFile.parent.create(recursive: true);
      
      await exportFile.writeAsString(exportData);
      return filePath;
      
    } catch (e) {
      Get.log('导出 Prompt 失败: $e');
      return null;
    }
  }

  /// 格式化导出数据 - Format Export Data
  String _formatExportData(PromptModel prompt, String format) {
    switch (format.toLowerCase()) {
      case 'json':
        return jsonEncode(prompt.toJson());
      case 'md':
        return '''# ${prompt.title}

## 描述
${prompt.description}

## 标签
${prompt.tags.join(', ')}

## 内容
${prompt.content}

---
*导出时间: ${DateTime.now().toIso8601String()}*
''';
      case 'txt':
        return '''${prompt.title}

描述: ${prompt.description}
标签: ${prompt.tags.join(', ')}
格式: ${prompt.getFormat()}
创建时间: ${prompt.createdAt.toIso8601String()}

内容:
${prompt.content}
''';
      default:
        return prompt.content;
    }
  }

  /// 获取存储统计信息 - Get Storage Statistics
  Future<Map<String, dynamic>> getStorageStatistics() async {
    try {
      final stats = <String, dynamic>{
        'total_prompts': 0,
        'formats': <String, int>{},
        'total_versions': 0,
        'storage_size': 0,
        'last_updated': DateTime.now().toIso8601String(),
      };
      
      // 统计 Prompt 数量 - Count Prompts
      for (final format in supportedFormats) {
        final formatDir = Directory(path.join(_promptsPath, format));
        if (await formatDir.exists()) {
          int count = 0;
          await for (final entity in formatDir.list()) {
            if (entity is Directory) count++;
          }
          stats['formats'][format] = count;
          stats['total_prompts'] += count;
        }
      }
      
      // 统计版本数量 - Count Versions
      final versionsDir = Directory(_versionsPath);
      if (await versionsDir.exists()) {
        await for (final entity in versionsDir.list()) {
          if (entity is Directory) {
            await for (final versionFile in entity.list()) {
              if (versionFile is File && versionFile.path.endsWith('.json')) {
                stats['total_versions']++;
              }
            }
          }
        }
      }
      
      // 计算存储大小 - Calculate Storage Size
      stats['storage_size'] = await _calculateDirectorySize(Directory(_baseStoragePath));
      
      return stats;
    } catch (e) {
      Get.log('获取存储统计信息失败: $e');
      return {};
    }
  }

  /// 计算目录大小 - Calculate Directory Size
  Future<int> _calculateDirectorySize(Directory directory) async {
    int size = 0;
    try {
      await for (final entity in directory.list(recursive: true)) {
        if (entity is File) {
          size += await entity.length();
        }
      }
    } catch (e) {
      Get.log('计算目录大小失败: $e');
    }
    return size;
  }

  /// 清理存储空间 - Clean Storage Space
  Future<void> cleanStorage() async {
    try {
      // 清理临时文件 - Clean temporary files
      final tempDir = Directory(path.join(_baseStoragePath, 'temp'));
      if (await tempDir.exists()) {
        await tempDir.delete(recursive: true);
      }
      
      // 清理过期的导出文件 - Clean expired export files
      final exportDir = Directory(path.join(_baseStoragePath, 'exports'));
      if (await exportDir.exists()) {
        final oneWeekAgo = DateTime.now().subtract(const Duration(days: 7));
        await for (final entity in exportDir.list()) {
          if (entity is File) {
            final stat = await entity.stat();
            if (stat.modified.isBefore(oneWeekAgo)) {
              await entity.delete();
            }
          }
        }
      }
      
      Get.log('存储空间清理完成');
    } catch (e) {
      Get.log('清理存储空间失败: $e');
    }
  }

  /// 备份数据 - Backup Data
  Future<String?> backupData({String? backupPath}) async {
    try {
      final timestamp = DateTime.now().millisecondsSinceEpoch;
      final backupFileName = 'prompt_manager_backup_$timestamp.zip';
      final outputPath = backupPath ?? path.join(_baseStoragePath, 'backups', backupFileName);
      
      // 这里应该实现压缩功能，暂时使用简单的目录复制 - Should implement compression here, temporarily use simple directory copy
      final backupDir = Directory(path.dirname(outputPath));
      await backupDir.create(recursive: true);
      
      // 创建备份信息文件 - Create backup info file
      final backupInfo = {
        'created_at': DateTime.now().toIso8601String(),
        'version': _config['version'],
        'total_prompts': (await getStorageStatistics())['total_prompts'],
        'backup_path': outputPath,
      };
      
      final backupInfoFile = File(path.join(path.dirname(outputPath), 'backup_info_$timestamp.json'));
      await backupInfoFile.writeAsString(jsonEncode(backupInfo));
      
      Get.log('数据备份完成: $outputPath');
      return outputPath;
      
    } catch (e) {
      Get.log('数据备份失败: $e');
      return null;
    }
  }

  /// 获取游客用户ID - Get Guest User ID
  String getGuestUserId() {
    return _config['guest_user_id'] as String? ?? 'guest_default';
  }

  /// 获取配置信息 - Get Configuration
  Map<String, dynamic> getConfig() {
    return Map<String, dynamic>.from(_config);
  }

  /// 更新配置 - Update Configuration
  Future<void> updateConfig(Map<String, dynamic> updates) async {
    _config.addAll(updates);
    await _saveConfiguration();
  }
}